/*
 * Copyright (c) 2024 Shenzhen Kaihong Digital Industry Development Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifdef __cplusplus
extern "C" {
#endif // __cplusplus

#include "sle_lite_tool_connect.h"

void OnSleTConnStateChangeCb(uint16_t connectId, const SleDeviceAddress *addr
        , SleConnectState connState, SlePairState pairState, SleDisConnectReason discReason)
{
    SLE_TEST_TOOL_LOG("[SleConnectTestTool] OnSleTConnStateChangeCb connectId = %d, addr = "MACSTR", connState = %s(%d), pairState = %s(%d), discReason = %s(%hhu)\n"
        , connectId, MAC2STR(addr->addr), SleConnectStateStr(connState), connState, SlePairStateStr(pairState), pairState, SleDisConnectReasonStr(discReason), discReason);
}

void OnSleTConnParamUpdatedCb(uint16_t connectId, SleErrorCode errCode, const SleConnectionParamUpdateEvt *connParam)
{
    SLE_TEST_TOOL_LOG("[SleConnectTestTool] OnSleTConnParamUpdatedCb connectId = %d, errCode = %hhu, connInterval = %d, connLatency = %d, connTimeout = %d\n",
        connectId, errCode, connParam->interval, connParam->latency, connParam->supervisionTimeout);
}

void TSleConnect(void)
{
    SleDeviceAddress remoteAddr = {
        .addrType = SLE_PUBLIC_ADDRESS_TYPE,
    };
    char addr[18];
    SleGetInputString("Please input remote device public addr(00:11:aa:bb:f1:6b)", addr, sizeof(addr));
    if(strlen(addr) != 17) {
        printf("[SleConnectTestTool] SleSetHostAddress failed, invalid addr\r\n");
        return;
    }
    Str2Mac(remoteAddr.addr, addr);
    SleErrorCode ret = SleConnect(&remoteAddr);
    if(ret != SLE_NO_ERROR) {
        printf("[SleConnectTestTool] SleConnect failed, ret:%hhu\r\n", ret);
        return;
    }
}

void TSleDisconnect(void)
{
    SleDeviceAddress remoteAddr = {
        .addrType = SLE_PUBLIC_ADDRESS_TYPE,
    };
    char addr[18];
    SleGetInputString("Please input remote device public addr(00:11:aa:bb:f1:6b)", addr, sizeof(addr));
    if(strlen(addr) != 17) {
        printf("[SleConnectTestTool] SleSetHostAddress failed, invalid addr\r\n");
        return;
    }
    Str2Mac(remoteAddr.addr, addr);
    SleErrorCode ret = SleDisconnect(&remoteAddr);
    if(ret != SLE_NO_ERROR) {
        printf("[SleConnectTestTool] SleDisconnect failed, ret:%hhu\r\n", ret);
        return;
    }
}

void TSleUpdateConnParam(void)
{
    SleConnectionParamUpdate param;
    param.connectId = (uint16_t)SleGetInputNumber("Please input connectId:");
    param.intervalMin = (uint16_t)SleGetInputNumber("Please input intervalMin:");
    param.intervalMax = (uint16_t)SleGetInputNumber("Please input intervalMax:");
    param.maxLatency = (uint16_t)SleGetInputNumber("Please input latency:");
    param.supervisionTimeout = (uint16_t)SleGetInputNumber("Please input supervisionTimeout:");
    SleErrorCode ret = SleUpdateConnParam(&param);
    if(ret != SLE_NO_ERROR) {
        SLE_TEST_TOOL_LOG("[SleConnectTestTool] SleUpdateConnParam failed, ret:%hhu", ret);
        return;
    }
}

void TSleUpdateAllConnParam(void)
{
    SleConnectDev successUpdateConnList[SLE_MAX_CONNECT_ID_NUM];
    uint16_t number = SLE_MAX_CONNECT_ID_NUM;
    SleErrorCode ret = SleUpdateAllConnParam(successUpdateConnList, &number);
    if(ret != SLE_NO_ERROR) {
        SLE_TEST_TOOL_LOG("[SleConnectTestTool] TSleUpdateAllConnParam failed, ret:%hhu", ret);
        return;
    }
    SLE_TEST_TOOL_LOG("[SleConnectTestTool] TSleUpdateAllConnParam number = %d\r\n", number);
    for (uint16_t i = 0; i < number; ++i) {
        SLE_TEST_TOOL_LOG("[SleConnectTestTool] TSleUpdateAllConnParam connectId = %d, addr = "MACSTR" \n",
          successUpdateConnList[i].connId, MAC2STR(successUpdateConnList->addr.addr));
    }
}

void TSleGetRecomSendDataSize(void)
{
    uint16_t connectId = (uint16_t)SleGetInputNumber("Please input connectId:");
    uint32_t recommendSendDataSize = 0;
    SleErrorCode ret = SleGetRecomSendDataSize(connectId, &recommendSendDataSize);
    if(ret != SLE_NO_ERROR) {
        SLE_TEST_TOOL_LOG("[SleConnectTestTool] TSleUpdateAllConnParam failed, ret:%hhu", ret);
        return;
    }
    SLE_TEST_TOOL_LOG("[SleConnectTestTool] TSleGetRecomSendDataSize connectId[%d] -- recommendSendDataSize[%d]\r\n",
                      connectId, recommendSendDataSize);
}

void TSendPairReq(void)
{
    SleDeviceAddress remoteAddr = {
        .addrType = SLE_PUBLIC_ADDRESS_TYPE,
    };
    char addr[18];
    SleGetInputString("Please input remote device public addr(00:11:aa:bb:f1:6b)", addr, sizeof(addr));
    if(strlen(addr) != 17) {
        printf("[SleConnectTestTool] SleSetHostAddress failed, invalid addr\r\n");
        return;
    }
    Str2Mac(remoteAddr.addr, addr);
    SleErrorCode ret = SendPairReq(&remoteAddr);
    if(ret != SLE_NO_ERROR) {
        printf("[SleConnectTestTool] SendPairReq failed, ret:%hhu\r\n", ret);
        return;
    }
}

void TRemovePair(void)
{
    SleDeviceAddress remoteAddr = {
        .addrType = SLE_PUBLIC_ADDRESS_TYPE,
    };
    char addr[18];
    SleGetInputString("Please input remote device public addr(00:11:aa:bb:f1:6b)", addr, sizeof(addr));
    if(strlen(addr) != 17) {
        printf("[SleConnectTestTool] SleSetHostAddress failed, invalid addr\r\n");
        return;
    }
    Str2Mac(remoteAddr.addr, addr);
    SleErrorCode ret = RemovePair(&remoteAddr);
    if(ret != SLE_NO_ERROR) {
        printf("[SleConnectTestTool] RemovePair failed, ret:%hhu\r\n", ret);
        return;
    }
}

void TRemoveAllPairs(void)
{
    SleErrorCode ret = RemoveAllPairs();
    if(ret != SLE_NO_ERROR) {
        printf("[SleConnectTestTool] RemoveAllPairs failed, ret:%d", ret);
        return;
    }
}

void TGetDevicePairState(void)
{
    SleDeviceAddress remoteAddr = {
        .addrType = SLE_PUBLIC_ADDRESS_TYPE,
    };
    char addr[18];
    SleGetInputString("Please input remote device public addr(00:11:aa:bb:f1:6b)", addr, sizeof(addr));
    if(strlen(addr) != 17) {
        printf("[SleConnectTestTool] GetDevicePairState failed, invalid addr\r\n");
        return;
    }
    Str2Mac(remoteAddr.addr, addr);
    SlePairState pairState;
    SleErrorCode ret = GetDevicePairState(&remoteAddr, &pairState);
    if(ret != SLE_NO_ERROR) {
        printf("[SleConnectTestTool] GetDevicePairState failed, ret:%hhu\r\n", ret);
        return;
    }
    SLE_TEST_TOOL_LOG("[SleConnectTestTool] GetDevicePairState success, pairState:%s(%hhu)", SlePairStateStr(pairState), pairState);
}

void TReadRemoteRssi(void)
{
    int8_t rssi;
    uint16_t  connectId = (uint16_t)SleGetInputNumber("Please input connectId:");
    SleErrorCode ret = ReadRemoteRssi(connectId, &rssi);
    if(ret != SLE_NO_ERROR) {
        printf("[SleConnectTestTool] ReadRemoteRssi failed, ret:%hhu\r\n", ret);
        return;
    }
    SLE_TEST_TOOL_LOG("[SleConnectTestTool] ReadRemoteRssi success, rssi:%d", rssi);
}

void TGetConnectDevList(void)
{
    SleConnectDev connectDevList[SLE_MAX_CONNECT_ID_NUM];
    uint16_t connectNum = SLE_MAX_CONNECT_ID_NUM;
    SleErrorCode ret = GetConnectDevList(connectDevList, &connectNum);
    if(ret != SLE_NO_ERROR) {
        printf("[SleConnectTestTool] GetConnectDevList failed, ret:%hhu\r\n", ret);
        return;
    }
    printf("[SleConnectTestTool] GetConnectDevList success, connectNum:%d connectDev:\r\n", connectNum);
    for(int i = 0; i< connectNum; i++) {
        printf("[SleConnectTestTool] list[%d]:[%d]"MACSTR"\r\n", i, connectDevList[i].connId, MAC2STR(connectDevList[i].addr.addr));
    }
}

void SleConnectToolHalper(void)
{
    printf("******SleConnectTool Command List*******\r\n");
    for (uint16_t i = 0; i < g_connectCmdNum; i++) {
        printf("*     %02d - %-20s     *\r\n", i, g_connectCmdList[i].desc);
    }
    printf("*************************************\r\n");
}

void SleConnectToolCmdHandler(int argc, char **argv)
{
    printf("SleConnectToolCmdHandler in\r\n");
    //试配uart接口的调用方式
    SleResetEnv();
    //从函数名字之后开始处理参数列表
    SleSetBufEnv(argc, argv, 1);
    int index = SleGetInputNumber("Please input cmd index:\r\n");
    if(index < g_connectCmdNum) {
        printf("cmd: %d\r\n", index);
        printf("Execute: %s\r\n", g_connectCmdList[index].desc);
        g_connectCmdList[index].func();
    }
    if(index != 0) g_connectCmdList[0].func();
}

#ifdef __cplusplus
}
#endif // __cplusplus
